import All_Exception.CheckExpansionException;
import All_Exception.CheckMyarrayList_isEmpty;
import All_Exception.CheckPosOnAddIllegality;

import java.util.Arrays;

public class MyArrayList implements SeqList {
    private static final int DEFULT_SIZE = 10;
    private int[] elem;
    private int size = 0;  //当前实际保存的的有效内容数量

    // 将顺序表的底层容量设置为init_capacity
    // 默认构造方法 : 自己构造，默认构造
    //1.默认构造
    public MyArrayList() {
        this.elem = new int[100];
    }

    //2.自己构造
    public MyArrayList(int Init_Capacity) {
        this.elem = new int[Init_Capacity];
    }

    //扩容
    private void Check_Capacity(int[] array) throws RuntimeException {
        if (this.elem.length == this.size) {  //满足扩容条件
            this.elem = Arrays.copyOf(array, this.elem.length * 2);

            //检查扩容前和扩容后的 size 和 array.length 还是否一致
            if (this.elem.length == this.size) {
                //扩容失败，发出异常警告
                throw new CheckExpansionException("扩容异常，请检查容量是否足够");
            }
        }
    }

    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //检查容量
        Check_Capacity(this.elem);
        this.elem[this.size++] = data;
    }

    /*
     * 在 pos 位置新增元素
     * 由于数据结构中每次存放数据时必须有一个前驱信息，所以能得到 pos 的合法位置应当为 pos >= 0 && pos < size + 1
     */
    public void add(int pos, int data) throws CheckPosOnAddIllegality {
        Check_Capacity(this.elem);
        int real_pos = pos - 1;

        CheckPosOnAdd(real_pos);

        if (real_pos == this.size || this.size == 0) {
            this.elem[real_pos] = data;
            this.size++;
            return;
        }
        int j = size - 1;
        for (int i = 0; i < this.size - real_pos; i++) {
            this.elem[j + 1] = this.elem[j--];
        }
        this.elem[real_pos] = data;
        this.size++;


    }

    private void CheckPosOnAdd(int real_pos) throws CheckPosOnAddIllegality {
        if (real_pos < 0 && real_pos > this.size + 1) {
            throw new CheckPosOnAddIllegality("当前pos出现异常，请检查输入");
        }
    }

    private Boolean isEmpty() {
        return this.size == 0;
    }

    // 判定是否包含某个元素
    public boolean contains(int toFind) throws CheckMyarrayList_isEmpty {
        if (isEmpty()) {
//        为空
            throw new CheckMyarrayList_isEmpty("顺序表为空！！!");
        }
        for (int i = 0; i < this.size; i++) {
            if (this.elem[i] == toFind) {
                System.out.println("找到了你所要查找的元素");
                return true;
            }
        }
        System.out.println("找不到你所要查找的元素");
        return false;
    }

    // 查找某个元素对应数组下标位置
    public int indexOf(int toFind) throws CheckMyarrayList_isEmpty {
        if (isEmpty()) {
//        为空
            throw new CheckMyarrayList_isEmpty("顺序表为空！！!");
        } else {
            for (int i = 0; i < this.size; i++) {
                if (this.elem[i] == toFind) {
                    return i + 1;
                }
            }
        }
        return -1;
    }

    // 获取 pos 位置的元素
    public int get(int pos) throws CheckMyarrayList_isEmpty, CheckPosOnAddIllegality {
        int real_pos = pos - 1;
        CheckPosOnAdd(real_pos);
        if (isEmpty()) {
//        为空
            throw new CheckMyarrayList_isEmpty("顺序表为空！！!");
        } else {
            return this.elem[real_pos];
        }
    }

    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) throws CheckMyarrayList_isEmpty, CheckPosOnAddIllegality {
        int real_pos = pos - 1;
        CheckPosOnAdd(real_pos);
        if (isEmpty()) {
//        为空
            throw new CheckMyarrayList_isEmpty("顺序表为空！！!");
        } else {
            this.elem[real_pos] = value;
        }
    }


    //删除关键字toRemove
    @Override
    public void remove(int toRemove) throws CheckMyarrayList_isEmpty {
        if (isEmpty()) {
//        为空
            throw new CheckMyarrayList_isEmpty("顺序表为空！！!");
        } else {
            for (int i = 0; i < this.size; i++) {
                if (this.elem[i] == toRemove) {
                    //删除
                    int key = i;
                    for (int j = 0; j < this.size - i - 1; j++) {
                        this.elem[key] = this.elem[key + 1];
                        key++;
                    }
                    this.size--;
                    return;
                }
            }
            System.out.println("无法找到你要删除的元素");
        }
    }

    // 获取顺序表长度
    public int size() {
        return this.size;
    }

    // 清空顺序表
    public void clear() {

//        for (int i = 0; i < this.size; i++)
//            this.elem[i] = null;
//        如果存储的是引用数据类型，则必须要把每个数组元素的引用置为空
        this.size = 0;
    }

    // 打印顺序表，注意：该方法并不是顺序表中的方法，为了方便看测试结果给出的
    public void display() {
        for (int i = 0; i < this.size; i++) {
            System.out.println("elem" + "[" + i + "]" + " = " + elem[i]);
        }
        System.out.println("顺序表当前长度为" + this.elem.length);
        System.out.println("size = " + this.size);
    }
}
